package com.sz.biz.trade.bill.service.impl;

import com.sz.biz.common.customer.entity.CusUser;
import com.sz.biz.common.sup.entity.Supplier;
import com.sz.biz.trade.bill.entity.TrdBillingOrderRel;
import com.sz.biz.common.AbstractVersionEntityService;
import com.sz.biz.common.customer.service.CustomerUserService;
import com.sz.biz.common.sup.service.SupplierService;
import com.sz.biz.common.sup.dto.SupplierDto;
import com.sz.biz.trade.bill.service.TrdBillingOrderRelService;
import com.sz.biz.trade.bill.dto.TrdBillingOrderListDto;
import com.sz.biz.trade.ord.service.TrdOrderService;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Function: 账单订单管理<br>
 * Author: changwentao <br>
 * Date: 2017-07-18 15:10:00
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class TrdBillingOrderRelServiceImpl extends AbstractVersionEntityService implements TrdBillingOrderRelService {


    private static final String TYPE = "type";
    @Autowired
    private TrdOrderService trdOrderService;
    @Autowired
    private CustomerUserService customerUserService;
    @Autowired
    private SupplierService supplierService;

    /**
     * 保存账单关联关系
     *
     * @param trdBillingOrderRel trdBillingOrderRel
     */
    @Override
    public void save(TrdBillingOrderRel trdBillingOrderRel) {
        dao.save(("TrdBillingOrderRelMapper.insertSelective"), trdBillingOrderRel);
    }

    /**
     * 根据账单号获取下属所有订单号
     *
     * @param billNos billNos
     * @return List
     */
    @Override
    public List<String> findOrderNosByBillNo(List<String> billNos) {
        ParamData paramData = new ParamData();
        paramData.put("billNos", billNos);
        return dao.findForList(("TrdBillingOrderRelMapper.findOrderNosByBillNo"), paramData, String.class);
    }

    /**
     * 根据账单号获取账单下所有订单
     *
     * @param billNo billNo
     * @return List
     */
    @Override
    public List<TrdBillingOrderListDto> findOrdersByBillNo(String billNo) {
        ParamData paramData = new ParamData();
        paramData.put("billNo", billNo);
        //根据条件获取账单列表
        return dao.findForList(getSqlName("findOrdersByBillNo"), paramData, TrdBillingOrderListDto.class);
    }


    /**
     * 根据账单号获取账单下所有订单
     *
     * @param params params
     * @return QResultDto
     */
    @Override
    public QResultDto getOrdersByBillNo(QueryParams params) {
        ParamData pd = convertQueryParams(params);
        //根据条件获取账单列表
        List<TrdBillingOrderListDto> billingList =
                dao.findForList(getSqlName("findOrdersByFilterListPage"), pd, TrdBillingOrderListDto.class);
        if (!CollectionUtils.isEmpty(billingList)) {
            billingList.forEach(item -> {
                String goodsNames = item.getGoodsNames().substring(1, item.getGoodsNames().length() - 1);
                item.setGoodsNames(goodsNames);
                if ((Integer) params.getParam().get(TYPE) == 2) {
                    Supplier sup = supplierService.findSimpleById(item.getCompanyId());
                    item.setCompanyName(sup.getName());
                    item.setCompanyUserName(sup.getCode());
                }
            });
        }
        return new QResultDto(billingList, pd.getPagination());
    }

    /**
     * 根据账单号获取账单下所有订单-客户平台
     *
     * @param billNo          billNo
     * @param orderNo         orderNo
     * @param goodsName       goodsName
     * @param custUserId      custUserId
     * @param startEffectTime startEffectTime
     * @param endEffectTime   endEffectTime
     * @param pageIndex       pageIndex
     * @param pageSize        pageSize
     * @param sort            sort
     * @param asc             asc
     * @return QResultDto
     */
    @Override
    public QResultDto getOrdersByBillNoForCustomer(int type, String billNo, String orderNo, String goodsName,
                                                   Integer custUserId, String startEffectTime, String endEffectTime,
                                                   int pageIndex, int pageSize, String sort, Boolean asc) {
        int loginUserId = PrincipalUtils.getAccountId();
        CusUser user = customerUserService.findById(loginUserId);
        //是否主帐号
        boolean isPrimaryAccount = isPrimaryAccount(loginUserId);
        //查询参数组装
        QueryParams params = new QueryParams(pageSize, pageIndex, "", sort, asc);
        params.put("type", type);
        params.put("bizCompanyId", user.getRefCustomerId());
        params.put("billNo", billNo);
        params.put("orderNo", orderNo);
        params.put("goodsName", StringUtils.replaceSqlPattern(goodsName));
        params.put("startEffectTime", StringUtils.isEmpty(startEffectTime) ? null : startEffectTime);
        params.put("endEffectTime", StringUtils.isEmpty(endEffectTime) ? null : endEffectTime);

        SupplierDto supplierDto = supplierService.findCurrTrdSupplier();
        if (isPrimaryAccount||null != supplierDto) {
            if(null != supplierDto){
                params.put("type", 3);
            }
            params.put("customerId", custUserId);
            return getOrdersByBillNo(params);
        } else {
            params.put("isSubAccount", 1);
            params.put("customerId", loginUserId);
        }

        ParamData pd = convertQueryParams(params);
        //根据条件获取账单列表
        List<TrdBillingOrderListDto> billingList =
                dao.findForList(getSqlName("findOrdersByFilterListPageForCustomer"), pd, TrdBillingOrderListDto.class);
        if (!CollectionUtils.isEmpty(billingList)) {
            billingList.forEach(item -> {
                String goodsNames = item.getGoodsNames().substring(1, item.getGoodsNames().length() - 1);
                item.setGoodsNames(goodsNames);
            });
        }

        return new QResultDto(billingList, pd.getPagination());
    }

    /**
     * 子帐号订单费用总计
     *
     * @param billNo billNo
     * @param finalIsSup
     *@param userId userId  @return Map
     */
    @Override
    public Map<String, Object> getOrderAmountSub(String billNo, Integer finalIsSup, Integer userId) {
        ParamData paramData = new ParamData();
        paramData.put("billNo", billNo);
        paramData.put("userId", userId);
        paramData.put("finalIsSup", finalIsSup);
        return (Map<String, Object>) dao.findForObject(("TrdBillingOrderRelMapper.getOrderAmountSub"), paramData);
    }

    /**
     * 是否主帐号
     *
     * @param customerId customerId
     * @return boolean
     */
    private boolean isPrimaryAccount(Integer customerId) {
        CusUser user = customerUserService.findById(customerId);
        return null != user && user.getIsSystem();
    }

    /**
     * 根据账单号删除
     *
     * @param billNo billNo
     */
    @Override
    public void deleteByBillNo(String billNo, int type) {
        List<String> billNos = new ArrayList<>();
        billNos.add(billNo);
        deleteByBillNos(billNos, type);
    }

    /**
     * 删除账单下所有订单
     *
     * @param billNos billNos
     */
    @Override
    public void deleteByBillNos(List<String> billNos, int type) {
        //获取账单下所有订单
        List<String> orderNos = findOrderNosByBillNo(billNos);
        if (CollectionUtils.isEmpty(orderNos)) {
            return;
        }
        //修改订单为没有生成过账单状态
        trdOrderService.updateIsBilledStatus(orderNos, type, false);
        ParamData paramData = new ParamData();
        paramData.put("billNos", billNos);
        dao.delete(("TrdBillingOrderRelMapper.deleteByBillNos"), paramData);
    }

    /**
     * 根据任务编码删除账单订单关联
     *
     * @param taskCodes taskCodes
     */
    @Override
    public void batchDeleteByTaskCodes(List<String> taskCodes, int type) {
        //获取账单下所有订单
        List<String> orderNos = findOrderNosByTaskCodes(taskCodes);
        if (CollectionUtils.isEmpty(orderNos)) {
            return;
        }
        //修改订单为没有生成过账单状态
        trdOrderService.updateIsBilledStatus(orderNos, type, false);
        ParamData paramData = new ParamData();
        paramData.put("taskCodes", taskCodes);
        dao.delete(("TrdBillingOrderRelMapper.batchDeleteByTaskCodes"), paramData);
    }
    /**
     * 根据任务编码删除账单订单关联
     *
     * @param taskCodes taskCodes
     */
    @Override
    public void batchDeleteByTaskCodesDraft(List<String> taskCodes, int type) {
        //获取账单下所有订单
        List<String> orderNos = findOrderNosByTaskCodesDraft(taskCodes);
        if (CollectionUtils.isEmpty(orderNos)) {
            return;
        }
        //修改订单为没有生成过账单状态
        trdOrderService.updateIsBilledStatus(orderNos, type, false);
        ParamData paramData = new ParamData();
        paramData.put("orderNos", orderNos);
        dao.delete(("TrdBillingOrderRelMapper.deleteByOrderNos"), paramData);
    }

    /**
     * 根据任务编码获取订单号
     *
     * @param taskCodes taskCodes
     * @return List
     */
    private List<String> findOrderNosByTaskCodes(List<String> taskCodes) {
        ParamData paramData = new ParamData();
        paramData.put("taskCodes", taskCodes);
        return dao.findForList(("TrdBillingOrderRelMapper.findOrderNosByTaskCodes"), paramData, String.class);
    }
    /**
     * 根据任务编码获取订单号
     *
     * @param taskCodes taskCodes
     * @return List
     */
    private List<String> findOrderNosByTaskCodesDraft(List<String> taskCodes) {
        ParamData paramData = new ParamData();
        paramData.put("taskCodes", taskCodes);
        return dao.findForList(("TrdBillingOrderRelMapper.findOrderNosByTaskCodesDraft"), paramData, String.class);
    }


    @Override
    protected String getMapperNamespace() {
        return "TrdBillingOrderRelMapper";
    }
}
